#pragma once

#include "vec.h"
#include "mat.h"
#include "MeshModel.h"
#include <string>

using namespace std;

//I'm pretty sure that's the factory design pattern.
class PrimMeshModel : public MeshModel{
public:
	PrimMeshModel(Renderer* r):MeshModel(r){}
	virtual ~PrimMeshModel(){};
	virtual void build(vec3 boundingBoxMin, vec3 boundingBoxMax)=0;//override to build specific primitive.

	virtual void someFunc(){cout<<"prim::someFunc\n";};
};

class Ark : public PrimMeshModel {
private:
	static const int numVertices = 8;
	static const int numFaces = 6*2; //2 triangles per square face
public:
	vec4 vBLC,vBLF,vTLC,vTLF,vBRC,vBRF,vTRC,vTRF;
public:
	Ark(Renderer* r):PrimMeshModel(r){};
	virtual void someFunc(){cout<<"someFunc\n";};
	virtual void build(vec3 boundingBoxMin=vec3(-0.5,-0.5,-0.5), vec3 boundingBoxMax=vec3(0.5,0.5,0.5)){
		vBLC = vec4(boundingBoxMin.x, boundingBoxMin.y, boundingBoxMin.z, 1);
		vBLF = vec4(boundingBoxMin.x, boundingBoxMin.y, boundingBoxMax.z, 1);
		vTLC = vec4(boundingBoxMin.x, boundingBoxMax.y, boundingBoxMin.z, 1);
		vTLF = vec4(boundingBoxMin.x, boundingBoxMax.y, boundingBoxMax.z, 1);
		vBRC = vec4(boundingBoxMax.x, boundingBoxMin.y, boundingBoxMin.z, 1);
		vBRF = vec4(boundingBoxMax.x, boundingBoxMin.y, boundingBoxMax.z, 1);
		vTRC = vec4(boundingBoxMax.x, boundingBoxMax.y, boundingBoxMin.z, 1);
		vTRF = vec4(boundingBoxMax.x, boundingBoxMax.y, boundingBoxMax.z, 1);
		
		modelDiameter = length(boundingBoxMin - boundingBoxMax);

		_vertices = vector<vec3>(numFaces * 3);
		_normals = vector<vec3>(numFaces * 3);
		
//bottom
		_vertices[0] = VEC4TOVEC3(vBLF);
		_vertices[1] = VEC4TOVEC3(vBLC);
		_vertices[2] = VEC4TOVEC3(vBRF);

		_vertices[3] = VEC4TOVEC3(vBRC);
		_vertices[4] = VEC4TOVEC3(vBRF);
		_vertices[5] = VEC4TOVEC3(vBLC);

//right
		_vertices[6] = VEC4TOVEC3(vBRF);
		_vertices[7] = VEC4TOVEC3(vBRC);
		_vertices[8] = VEC4TOVEC3(vTRF);

		_vertices[9] = VEC4TOVEC3(vTRF);
		_vertices[10] = VEC4TOVEC3(vBRC);
		_vertices[11] = VEC4TOVEC3(vTRC);

//top
		_vertices[12] = VEC4TOVEC3(vTRF);
		_vertices[13] = VEC4TOVEC3(vTRC);
		_vertices[14] = VEC4TOVEC3(vTLF);

		_vertices[15] = VEC4TOVEC3(vTLF);
		_vertices[16] = VEC4TOVEC3(vTRC);
		_vertices[17] = VEC4TOVEC3(vTLC);

//left
		_vertices[18] = VEC4TOVEC3(vTLF);
		_vertices[19] = VEC4TOVEC3(vTLC);
		_vertices[20] = VEC4TOVEC3(vBLF);

		_vertices[21] = VEC4TOVEC3(vBLF);
		_vertices[22] = VEC4TOVEC3(vTLC);
		_vertices[23] = VEC4TOVEC3(vBLC);

//front
		_vertices[24] = VEC4TOVEC3(vTLC);
		_vertices[25] = VEC4TOVEC3(vTRC);
		_vertices[26] = VEC4TOVEC3(vBLC);

		_vertices[27] = VEC4TOVEC3(vBLC);
		_vertices[28] = VEC4TOVEC3(vTRC);
		_vertices[29] = VEC4TOVEC3(vBRC);

//rear
		_vertices[30] = VEC4TOVEC3(vTRF);
		_vertices[31] = VEC4TOVEC3(vTLF);
		_vertices[32] = VEC4TOVEC3(vBRF);

		_vertices[33] = VEC4TOVEC3(vBRF);
		_vertices[34] = VEC4TOVEC3(vTLF);
		_vertices[35] = VEC4TOVEC3(vBLF);
	}

	virtual void drawVertexNormals() {
	}

	virtual void draw(){
		this->m_renderer->SetObjectMatrices(this->_world_transform,NULL);
		m_renderer->setNormalLength(modelDiameter);
		this->m_renderer->DrawTriangles(&(this->_vertices),&(this->_normals));
		this->m_renderer->drawVertexNormals(&(this->_vertices),&(this->_normals));
	}
};